package com.itheima.advice;

import cn.hutool.json.JSONUtil;
import com.itheima.mapper.OperateLogMapper;
import com.itheima.pojo.*;
import com.itheima.utlis.CurrentHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Aspect
@Component
@Slf4j
public class RecordLogAdvice {

    @Autowired
    private OperateLogMapper operateLogMapper;



    @Around("@annotation(com.itheima.advice.RecordLogAnno)")
    public Object log ( ProceedingJoinPoint pjp ) throws Throwable {

        System.out.println("RecordLogAdvice使用的线程名称是：" + Thread.currentThread().getName());
        //开始时间
        long begin = System.currentTimeMillis();

        //执行业务方法
        Object result = pjp.proceed();
        //结束时间
        long end = System.currentTimeMillis();


        //获取类名
        String className = pjp.getTarget().getClass().getName();
        //获取方法名
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        String methodName = signature.getMethod().getName();
        //获取参数
        Object[] args = pjp.getArgs();

        // 创建日志的实体类
        OperateLog operateLog = new OperateLog();

        operateLog.setOperateEmpId(getCurrentUserId()); //操作人
        operateLog.setOperateTime(LocalDateTime.now());
        operateLog.setClassName(className);
        operateLog.setMethodName(methodName);
        if (args != null && args.length > 0) {
            operateLog.setMethodParams(JSONUtil.toJsonStr(args));
            //把对象转成json字符串  需要导入Hutool的依赖
            //  <dependency>
            //     <groupId>cn.hutool</groupId>
            //     <artifactId>hutool-all</artifactId>
            //     <version>5.8.40</version>
            // </dependency>
        }
        if (result != null) {
            operateLog.setReturnValue(JSONUtil.toJsonStr(result));  //方法的返回值
        }

        operateLog.setCostTime(end - begin); //花费的时间

        operateLogMapper.insert(operateLog);

        return result;
    }

    @Around("@annotation(com.itheima.advice.RecordLoginAnno)")
    public Object login ( ProceedingJoinPoint pjp ) throws Throwable {
        long begin = System.currentTimeMillis();
        Object result = null;
        EmpDot empDot = null;

        Object[] args = pjp.getArgs();

        empDot = (EmpDot) args[0];


        boolean isLoginSuccess = false;
        String jwtToken = null;
        try {
            result = pjp.proceed();
            isLoginSuccess = true;

            if (result instanceof Result) {
                Result resultObj = (Result) result;
                Object data = resultObj.getData();
                if (data instanceof LoginInfo) {
                    jwtToken = ((LoginInfo) data).getToken();
                }
            }
        } catch (RuntimeException e) {

            isLoginSuccess = false;

            throw e;
        } finally {

            long end = System.currentTimeMillis();
            EmpLoginLog empLoginLog = new EmpLoginLog();

            if (empDot != null) {
                empLoginLog.setUsername(empDot.getUsername());
                empLoginLog.setPassword(empDot.getPassword());
            }

            empLoginLog.setLoginTime(LocalDateTime.now());
            empLoginLog.setIsSuccess(isLoginSuccess ? (short) 1 : (short) 0);
            empLoginLog.setJwt(jwtToken);
            empLoginLog.setCostTime(end - begin);

            operateLogMapper.insertLog(empLoginLog);
        }

        return result;
    }

    public Integer getCurrentUserId () {
        System.out.println("当前用户的id" + CurrentHolder.getUserId());
        return CurrentHolder.getUserId();
    }
}